package fuzion24.device.vulnerability.vulnerabilities.framework.graphics;

import android.content.Context;
import android.os.Build;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import fuzion24.device.vulnerability.util.CPUArch;
import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;

/**
 * Created by fuzion24 on 9/15/15.
 */
public class GraphicBufferTest implements VulnerabilityTest {

    private final static String TAG = "GraphicsBuffer";

    private enum AndroidVersions{
        JELLYBEAN_AND_EARLIER(0),
        KITKAT_AND_LOLLIPOP(1),
        MARSHMELLOW(2),
        OTHER(99);

        private final int ver;
        private AndroidVersions(int ver)
        {
            this.ver = ver;
        }
        public int getIntCode(){
            return ver;
        };
    }

    static {
        System.loadLibrary("graphicsbufferoverflow");
    }

    @Override
    public String getCVEorID() {
        return "CVE-2015-1474";
    }

    @Override
    public List<CPUArch> getSupportedArchitectures() {
        ArrayList<CPUArch> archs = new ArrayList<>();
        archs.add(CPUArch.ARM);
        archs.add(CPUArch.ARM7);
        archs.add(CPUArch.ARM8);
        return archs;
    }

    private native int checkGraphicsBuffer(int ver);

    @Override
    public boolean isVulnerable(Context context) throws Exception {
        int checkVal;

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            Log.d(TAG, "Running with KK and Lollipop types");
            checkVal = checkGraphicsBuffer(AndroidVersions.KITKAT_AND_LOLLIPOP.getIntCode());
        }else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){
            checkVal = checkGraphicsBuffer(AndroidVersions.JELLYBEAN_AND_EARLIER.getIntCode());
        }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            checkVal = checkGraphicsBuffer(AndroidVersions.MARSHMELLOW.getIntCode());
        }else{
            checkVal = checkGraphicsBuffer(AndroidVersions.OTHER.getIntCode());
        }

        //TODO: If we declare a different type of socket do we still need internet permission?
        if(checkVal == 0) {
            return false;
        }else if(checkVal == 1) {
            return true;
        }else {
            //TODO: grab more information about failure, errno and error string
            throw new Exception("Error running test");
        }
    }
}